package com.imooc.service.impl;

import com.imooc.enums.Sex;
import com.imooc.mapper.UsersMapper;
import com.imooc.pojo.Users;
import com.imooc.pojo.bo.UserBO;
import com.imooc.service.UserService;
import com.imooc.utils.DateUtil;
import com.imooc.utils.MD5Utils;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UsersMapper usersMapper;
    @Autowired
    private Sid sid;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public boolean queryUsernameIsExist(String username) {
        Example userExample = new Example(Users.class);
        Example.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andEqualTo("username", username);
        Users result = usersMapper.selectOneByExample(userExample);
        return result != null;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Users createUser(UserBO userBO) {
        Users user = new Users();
        user.setId(sid.nextShort());
        user.setUsername(userBO.getUsername());

        // 密码加密
        try {
            user.setPassword(MD5Utils.getMD5Str(userBO.getPassword()));
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 默认用户昵称同用户名
        user.setNickname(userBO.getUsername());
        // 默认头像
        user.setFace("https://static.ieasydog.com/dog/1576460320578.jpg");
        // 默认生日
        user.setBirthday(DateUtil.stringToDate("1900-01-01"));
        // 默认性别为保密
        user.setSex(Sex.secret.type);
        user.setCreatedTime(new Date());
        user.setUpdatedTime(new Date());
        usersMapper.insert(user);

        return user;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Users queryUserForLogin(String username, String password) {
        Example userExample = new Example(Users.class);
        Example.Criteria userCriteria = userExample.createCriteria();
        userCriteria.andEqualTo("username", username);
        userCriteria.andEqualTo("password", password);
        Users result = usersMapper.selectOneByExample(userExample);
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public Users getUsersInfo(int id) {
        return usersMapper.selectByPrimaryKey(id);
    }

    /**
     * 事务传播 - Propagation
     * REQUIRED: 使用当前的事务,如果当前没有事务, 则自己新建一个事务, 子方法是必须运行在一个事务中的;
     *           如果当前存在事务, 则加入这个事务, 成为一个整体; (使用最多)
     *           举例: 领导没饭吃, 我有钱, 我会自己买了自己吃; 领导有的吃, 会分给你一起吃.
     * SUPPORTS: 若果当前有事务, 则使用事务; 如果当前没有事务, 则不使用事务. (用于查询)
     *           举例: 领导没饭吃, 我也没饭吃; 领导有饭吃, 我也有饭吃.
     * MANDATORY: 该传播属性强制必须存在一个事务, 如果不存在, 则抛出异常
     *            举例: 领导必须管饭, 不管饭没饭吃, 我就不乐意了, 就不干了 (抛出异常)
     * REQUIRES_NEW: 如果当前有事务, 则挂起该事务, 并且自己创建一个新的事务给自己使用;
     *               如果当前没有事务, 则同 REQUIRED
     *               举例: 领导有饭吃, 我偏不要, 我自己买了自己吃.
     * NOT_SUPPORTED: 如果当前有事务, 则把事务挂起, 自己不使用事务去运行数据库操作(查询)
     *                举例: 领导有饭吃, 分一点给你, 我太忙了, 放一边, 我不吃
     * NEVER: 如果当前有事务存在, 则抛出异常
     *        举例: 领导有饭给你吃, 我不想吃, 我热爱工作, 我抛出异常
     * NESTED: 如果当前有事务, 则开启子事务 (嵌套事务, 独立提交或者回滚);
     *         如果当前没有事务, 则同 REQUIRED
     *         但是如果主事务提交, 则会携带子事务一起提交.
     *         如果主事务回滚, 则子事务会一起回滚. 相反, 子事务异常, 则父事务可以回滚或不回滚.
     *         举例: 领导决策不对, 老板怪罪, 领导带着小弟一同受罪. 小弟出了差错, 领导可以推卸责任.
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void saveUsers() {
        Users users = new Users();
        users.setId("1");
        users.setFace("https://static.ieasydog.com/dog/1576460320578.jpg");
        users.setUsername("13291825113");
        users.setPassword("123456");
        users.setNickname("wangjunte");
        users.setRealname("王君特");
        users.setMobile("13291825113");
        users.setSex(1);
        users.setEmail("444706015@qq.com");
        users.setCreatedTime(new Date());
        users.setUpdatedTime(new Date());
        usersMapper.insertSelective(users);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void updateUsers(int id) throws ParseException {
        Users users = new Users();
        users.setId(String.valueOf(id));
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date birthday = dateFormat.parse("1990-07-25");
        users.setBirthday(birthday);
        usersMapper.updateByPrimaryKeySelective(users);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void deleteUsers(int id) {
        usersMapper.deleteByPrimaryKey(id);
    }
}
